/**
 * 
 */
package logic.algorithm;

import java.util.List;
import java.util.LinkedList;

import datamodel.Grid;
import datamodel.GridElementState;
import datamodel.Grid.Neighbors;
import datamodel.GridElement;

/**
 * @author Marc, Kevin Munk
 * @version 0.1
 *
 */
public class MooreAlgorithm implements Algorithm {
	public Grid  grid;
	public List<GridElement> waitsnake = new LinkedList<GridElement>();
	public GridElement start;
	public GridElement end;

	/* (non-Javadoc)
	 * @see logic.algorithm.Algorithm#init(datamodel.Grid)
	 */
	@Override
	public void init(Grid grid) {
		this.grid = grid;
		this.start = grid.getStartElement();
		this.end = grid.getEndElement();
		
		for(int row = 0;row<grid.getRows(); row++){
			for(int column = 0 ;column<grid.getColumns();column++){
				if( !grid.getElementAt(row, column).getState().equals(GridElementState.BLOCKED)){
				grid.getElementAt(row,column).setDistance(Integer.MAX_VALUE);
			}}
		}
		waitsnake.add(start);
		start.setDistance(0);
	}

	/* (non-Javadoc)
	 * @see logic.algorithm.Algorithm#doNextStep()
	 */
	@Override
	public boolean doNextStep() {
		while(!waitsnake.isEmpty()){
			GridElement gr = waitsnake.remove(0);
			
			Neighbors neighbors = grid.getNeighborsFrom(gr, false);
			for(int n = 0; n < neighbors.getNeighbors().size(); n++){
				GridElement node  = neighbors.getNeighbors().get(n);
				
				if (node.getDistance() == Integer.MAX_VALUE ){
					node.setPrevious(gr);
					node.setDistance(gr.getDistance()+ neighbors.getWayCosts().get(n));
					waitsnake.add(node);
				}
		}}
		if(waitsnake.isEmpty()){
			return false;
		}
		else return isSolved();
	}

	/* (non-Javadoc)
	 * @see logic.algorithm.Algorithm#isSolved()
	 */
	@Override
	public boolean isSolved() {
		if(end.getDistance() != Integer.MAX_VALUE){
			return true;
		}else return false;
	}
	
	

}
